export type Position = {
  x: number
  y: number
}
export enum Gesture { // 只处理，left right
  NONE,
  UP,
  DOWN,
  LEFT,
  RIGHT
}
export type HammingPositionInfo = {
  endPos: Position
  startPos: Position
}
export type HammingEventCallback = (position: HammingPositionInfo) => void
export type HammingEvents = {
  onSwipeLeft?: HammingEventCallback
  onSwipeRight?: HammingEventCallback
  onSwipeTop?: HammingEventCallback
  onSwipeDown?: HammingEventCallback
}

import { ref } from "vue"

export const useTouchMove = (
  minHammingDistance: number,
  hammingEvents: HammingEvents,
  needPreventDefault: Boolean = false
): {
  onTouchEnd: (e: TouchEvent) => void
  onTouchMove: (e: TouchEvent) => void
  onTouchStart: (e: TouchEvent) => void
} => {
  const startPos = ref<Position>({ x: 0, y: 0 })
  const endPos = ref<Position>({ x: 0, y: 0 })
  const gesture = ref<Gesture>(Gesture.NONE)
  const reset = () => {
    startPos.value = { x: 0, y: 0 }
    endPos.value = { x: 0, y: 0 }
    gesture.value = Gesture.NONE
  }
  const onTouchStart = (e: TouchEvent) => {
    reset()
    startPos.value = {
      x: e.targetTouches[0].pageX,
      y: e.targetTouches[0].pageY
    }
  }
  const onTouchMove = (e: TouchEvent) => {
    endPos.value = {
      x: e.targetTouches[0].pageX,
      y: e.targetTouches[0].pageY
    }
    const dx = endPos.value.x - startPos.value.x
    const dy = endPos.value.y - endPos.value.y
    if (dx === 0 && dy == 0) {
      // 恢复默认事件
      // window.event.returnValue = true
      return
    }
    if (needPreventDefault) {
      e.preventDefault()
    }
    if (Math.abs(dx) > Math.abs(dy)) {
      if (dx < 0 && minHammingDistance + dx <= 0) {
        gesture.value = Gesture.LEFT
        return
      }
      if (dx > 0 && dx - minHammingDistance >= 0) {
        gesture.value = Gesture.RIGHT
        return
      }
    }
    if (Math.abs(dx) < Math.abs(dy)) {
      if (dy < 0 && minHammingDistance + dy <= 0) {
        gesture.value = Gesture.UP
        return
      }
      if (dy > 0 && minHammingDistance - dy >= 0) {
        gesture.value = Gesture.DOWN
        return
      }
    }
  }
  const onTouchEnd = () => {
    const position = { endPos: endPos.value, startPos: startPos.value }
    switch (gesture.value) {
      case Gesture.UP:
        // @ts-ignore
        hammingEvents?.onSwipeTop(position)
        break
      case Gesture.DOWN:
        // @ts-ignore
        hammingEvents?.onSwipeDown(position)
        break
      case Gesture.LEFT:
        // @ts-ignore
        hammingEvents?.onSwipeLeft(position)
        break
      case Gesture.RIGHT:
        // @ts-ignore
        hammingEvents?.onSwipeRight(position)
        break
    }
  }
  return {
    onTouchEnd,
    onTouchMove,
    onTouchStart
  }
}
